function identity<T>(arg: T): T {
    return arg;
}
identity<string>("hello")
identity("world");

function loggingIdentity<T>(arg: T): T {
    console.log(arg.length);  // Error: T doesn't have .length
    return arg;
}

function loggingIdentity2<T>(arg: T[]): T[] {
    console.log(arg.length);  // Array has a .length, so no more error
    return arg;
}

function loggingIdentity3<T>(arg: Array<T>): Array<T> {
    console.log(arg.length);  // Array has a .length, so no more error
    return arg;
}

function identity7<T>(arg: T): T {
    return arg;
}

let myIdentity: <T>(arg: T) => T = identity7;

function identity2<T>(arg: T): T {
    return arg;
}

let myIdentity2: <U>(arg: U) => U = identity2;

function identity3<T>(arg: T): T {
    return arg;
}

let myIdentity3: {<T>(arg: T): T} = identity3;



interface GenericIdentityFn {
    <T>(arg: T): T;
}

function identity5<T>(arg: T): T {
    return arg;
}

let myIdentity5: GenericIdentityFn = identity5;


interface GenericIdentityFn2<T> {
    (arg: T): T;
}

function identity22<T>(arg: T): T {
    return arg;
}

let myIdentity22: GenericIdentityFn2<number> = identity22;